home *** CD-ROM | disk | FTP | other *** search
/ Creative Computers / Creative Computers CD-ROM, Volume 1 (Legendary Design Technologies, Inc.)(1994).iso / shareware / games / uchess / src / search.c < prev    next >
C/C++ Source or Header  |  1994-11-17  |  51KB  |  1,905 lines

  1. //char strx[40];
  2. #define CLEARHISTBETWEENMOVES // old way to handle hist table
  3. /*
  4.  * search.c - C source for GNU CHESS
  5.  *
  6.  * Copyright (c) 1988,1989,1990 John Stanback Copyright (c) 1992 Free Software
  7.  * Foundation
  8.  *
  9.  * This file is part of GNU CHESS.
  10.  *
  11.  * GNU Chess is free software; you can redistribute it and/or modify it under
  12.  * the terms of the GNU General Public License as published by the Free
  13.  * Software Foundation; either version 2, or (at your option) any later
  14.  * version.
  15.  *
  16.  * GNU Chess is distributed in the hope that it will be useful, but WITHOUT ANY
  17.  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  18.  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
  19.  * details.
  20.  *
  21.  * You should have received a copy of the GNU General Public License along with
  22.  * GNU Chess; see the file COPYING.  If not, write to the Free Software
  23.  * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  24.  */
  25. #include "gnuchess.h"
  26.  
  27. #define ZEROALLBETWEENPLY 1
  28.  
  29. #ifdef QUIETBACKGROUND
  30. short __aligned background = 0;
  31.  
  32. #endif /* QUIETBACKGROUND */
  33. static short int __aligned DepthBeyond;
  34. short __aligned Threat[MAXDEPTH];
  35. unsigned short int __aligned PrVar[MAXDEPTH];
  36. extern short int ISZERO;
  37. extern long EADD,EGET;
  38. extern char mvstr[4][6];
  39. extern short int recycle;
  40. extern int trying_again;
  41. short int __aligned myflagdeepnull=0xff;
  42. int got_20000=0;
  43. short __aligned ThreatSave[MAXDEPTH]; /* tom@izf.tno.nl */
  44. extern short __aligned QueenCheck[MAXDEPTH]; /* tom@izf.tno.nl */
  45. #if defined NULLMOVE || defined DEEPNULL
  46. short int __aligned no_null;
  47. short int __aligned null;         /* Null-move already made or not */
  48. short int __aligned PVari;        /* Is this the PV */
  49. #endif
  50. #ifdef DEBUG40
  51. extern int whichway;
  52. #endif
  53. #ifdef DEBUG
  54. unsigned short __aligned DBLINE[MAXDEPTH];
  55. struct leaf __aligned *dbptr;
  56.  
  57. #endif
  58. short __aligned start_stage;
  59. short __aligned thrashing_tt; /* must we recycle slots at random. TomV */
  60. short int __aligned zwndw;
  61.  
  62. #include "ataks3.h"
  63.  
  64. #define __USE_SYSBASE
  65. #include <proto/exec.h>
  66.  
  67. extern long OrigResponse;
  68. extern int global_tmp_score;
  69. extern int previous_score;
  70. short __aligned myflagpvs=true;
  71. int __aligned backsrchaborted=0;
  72. int __aligned Sdepth2=0;
  73. extern int MoveNowOK;
  74. extern int procpri;
  75. extern struct Process *myproc;
  76.  
  77.  
  78. #ifdef SPEED_PRECALC
  79. unsigned short __aligned PreCalcedHint;
  80. unsigned short __aligned PreCalcedMove;
  81. int DoPreCalc (unsigned INTSIZE *, INTSIZE);
  82. #endif
  83. int __aligned Castled[2]={0,0};
  84. int __aligned myEnPassant[2]={0,0};
  85.  
  86.  
  87.  
  88. inline short int repetition (void);
  89.  
  90.  
  91. #include "debug41.h"
  92. /* ............    MOVE GENERATION & SEARCH ROUTINES    .............. */
  93.  
  94. #ifndef STRAIGHT4PL68
  95. // improved Kong Sian Repetition
  96.  
  97. inline
  98. short int
  99. repetition ()
  100.  
  101. /*  Check for draw by threefold repetition.  */
  102.  
  103. {
  104.   register short i, cnt;
  105.  
  106.   cnt = 0;
  107.   /* try to avoid work */
  108.   if (GameCnt > Game50 + 3)
  109.     for (i = GameCnt; i >= Game50; i--)
  110.       if (hashbd == GameList[i].hashbd && hashkey == GameList[i].hashkey)
  111.         cnt++;
  112.  
  113.   return cnt;
  114. }
  115.  
  116. #else // straight 4pl68 repetition
  117. inline
  118. short int
  119. repetition ()
  120.  
  121. /*  Check for draw by threefold repetition.  */
  122.  
  123. {
  124.   register short i, c,cnt;
  125.   register unsigned short m;
  126.   short b[64];
  127.  
  128.   cnt = c = 0;
  129.   /* try to avoid work */
  130.   if (GameCnt > Game50 + 3) // changed from gamecnt+4
  131.     {
  132. #if defined(NOMEMSET) || defined(MSDOS)
  133.       for (i = 0; i < 64; b[i++] = 0);
  134. #else
  135. #ifndef AMIGA
  136.       memset ((char *) b, 0, (unsigned long)sizeof (b));
  137. #else
  138.       ClearMem(b,sizeof (b));
  139. #endif
  140. #endif /* NOMEMSET */
  141.       for (i = GameCnt; i >= Game50; i--)
  142.     {
  143.       m = GameList[i].gmove;
  144.       /* does piece exist on diff board? */
  145.       if (b[m & 0x3f])
  146.         {
  147.           /* does diffs cancel out, piece back? */
  148.           if ((b[m >> 8] += b[m & 0x3f]) == 0)
  149.         --c;
  150.           b[m & 0x3f] = 0;
  151.         }
  152.       else
  153.         {
  154.           /* create diff */
  155.           ++c;
  156.           /* does diff cancel out another diff? */
  157.           if (!(b[m >> 8] -= (b[m & 0x3f] = board[m & 0x3f] +
  158.                   (color[m & 0x3f] << 8))))
  159.         --c;
  160.         }
  161.       /* if diff count is 0 we have a repetition */
  162.       if (c == 0)
  163.         if ((i ^ GameCnt) & 1)
  164.           cnt++;
  165.     }
  166.     }
  167.     return cnt;
  168. }
  169. #endif // striaght 4pl68 repetition
  170.  
  171. int plyscore, globalscore;
  172. int
  173. pick (short int p1, short int p2)
  174.  
  175. /*
  176.  * Find the best move in the tree between indexes p1 and p2. Swap the best
  177.  * move into the p1 element.
  178.  *
  179.  */
  180. {
  181.   register struct leaf *p, *q, *r, *k;
  182.   register s0;
  183.   struct leaf temp;
  184.  
  185.   k = p = &Tree[p1];
  186.   q = &Tree[p2];
  187.   s0 = p->score;
  188.   for (r = p + 1; r <= q; r++)
  189.     if ((r->score) > s0)
  190.       {
  191.     s0 = (r->score);
  192.     p = r;
  193.       }
  194.   if (p != k)
  195.     {
  196.       temp = *p;
  197.       *p = *k;
  198.       *k = temp;
  199.       return true;
  200.     }
  201.   return false;
  202. }
  203.  
  204. #ifdef DEBUG
  205. unsigned short trace[MAXDEPTH];
  206. char traceline[256];
  207. unsigned short tracelog[MAXDEPTH];
  208. int tracen = 0;
  209. int traceflag = 0;
  210. int traceply = 0;
  211. #endif
  212. int __aligned bookflag = false;
  213. int __aligned Jscore = 0;
  214.  
  215. static int __aligned TCcount, TCleft;
  216. void
  217. SelectMove (short int side, short int iop)
  218.  
  219.  
  220. /*
  221.  * Select a move by calling function search() at progressively deeper ply
  222.  * until time is up or a mate or draw is reached. An alpha-beta window of
  223.  * -Awindow to +Bwindow points is set around the score returned from the
  224.  * previous iteration. If Sdepth != 0 then the program has correctly
  225.  * predicted the opponents move and the search will start at a depth of
  226.  * Sdepth+1 rather than a depth of 1.
  227.  */
  228.  
  229. {
  230.   static short int i, tempb, tempc, tempsf, tempst, xside, rpt;
  231.   static short int alpha, beta, score;
  232.   static struct GameRec *g;
  233.   int earlyflag;
  234.  
  235. #ifndef CLEARHISTBETWEENMOVES // old way to handle hist table
  236.   int cnt;
  237.   ULONG *tmphistptr;
  238. #endif
  239.  
  240.   char mystr[16];
  241.   short InChkDummy;
  242.   short start_score;
  243. #ifdef DEBUG
  244.  
  245. if(debuglevel & (512|1024)){
  246.     char b[32];
  247.     short c1,c2,r1,r2;
  248. tracen=0;
  249. traceflag = false;
  250. traceply = 0;
  251. tracelog[0]=0;
  252. while(true){
  253.     /*printf("debug?");
  254.     gets(b);*/
  255.     if(b[0] == 'p')traceply = atoi(&b[1]);
  256.     else
  257.     if(b[0] == '\0')break;
  258.     else{
  259.         c1 = b[0] - 'a';
  260.               r1 = b[1] - '1';
  261.               c2 = b[2] - 'a';
  262.               r2 = b[3] - '1';
  263.               trace[++tracen] = (locn (r1, c1) << 8) | locn (r2, c2);
  264.     }
  265.     if(tracen == 0 && traceply >0)traceflag = true;
  266.     }
  267.     
  268. }
  269. #endif
  270.  
  271. //  InitializeStats(); // MY FIX FOR UNDO PROBLEMS!!! TMP!!!
  272.  
  273. got_20000 = 0;
  274. start_again:
  275.   flag.timeout = false;
  276.   flag.back = flag.musttimeout = false;
  277.   xside = side ^ 1;
  278.   recycle = (GameCnt % rehash) - rehash;
  279.   /* if background mode set to infinite */
  280.   if (iop == 2)
  281.     {
  282.       Sdepth2 = 0;
  283.       (void)SetTaskPri((struct Task *)myproc,0);
  284.       OrigResponse = ResponseTime = 9999999;
  285. #ifdef QUIETBACKGROUND
  286.       background = true;
  287. #endif /* QUIETBACKGROUND */
  288.     }
  289.   else
  290.     {
  291.       player = side;
  292.       if (TCflag)
  293.     {
  294.       TCcount = 0;
  295. #ifdef QUIETBACKGROUND
  296.       background = false;
  297. #endif /* QUIETBACKGROUND */
  298.       if (TimeControl.moves[side] < 1)
  299.         TimeControl.moves[side] = 1;
  300.       /* special case time per move specified */
  301.       if (flag.onemove)
  302.         {
  303.           OrigResponse = ResponseTime = TimeControl.clock[side] - 100;
  304.           TCleft = 0;
  305.         }
  306.       else
  307.         {
  308.           /* calculate avg time per move remaining */
  309.           TimeControl.clock[side] += TCadd;
  310.  
  311.           ResponseTime = (TimeControl.clock[side]) / (((TimeControl.moves[side]) * 2) + 1);
  312.           TCleft = (int)ResponseTime / 3;
  313.           ResponseTime += TCadd/2;
  314.           if (TimeControl.moves[side] < 5)
  315.         TCcount = MAXTCCOUNTX - 1;
  316.         }
  317.       if (ResponseTime < 101)
  318.         {
  319.           ResponseTime = 100;
  320.           TCcount = MAXTCCOUNTX;
  321.         }
  322.       else if (ResponseTime < 200)
  323.         {
  324.           TCcount = MAXTCCOUNTX - 1;
  325.         }
  326.           OrigResponse = ResponseTime;
  327.           if ((TimeControl.moves[side] > 9))
  328.            ResponseTime += 51;
  329. //           ResponseTime = ResponseTime + (ResponseTime/4); // ADDED TO 2.50 to make clock better
  330.     }
  331.       else
  332.        {
  333. #ifdef QUIETBACKGROUND
  334.       background = false;
  335. #endif /* QUIETBACKGROUND */
  336.     OrigResponse = ResponseTime = MaxResponseTime;
  337.        }
  338.       if (TCleft)
  339.     {
  340.       TCcount = ((int)((TimeControl.clock[side] - ResponseTime)) / 2) / TCleft;
  341.       if (TCcount > MAXTCCOUNTX)
  342.         TCcount = 0;
  343.       else
  344.         TCcount = MAXTCCOUNTX - TCcount;
  345.     }
  346.       else
  347.     TCcount = M